package com.itcast.chapter01;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Map;

/**
 * @author : zjj
 * @date : 2022/9/5 16:20
 */

@SpringBootApplication
public class ApplicationChapter01 {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        /**
         * 会返回一个Spring容器 ， ConfigurableApplicationContext
         */
        ConfigurableApplicationContext applicationContext = SpringApplication.run(ApplicationChapter01.class, args);

        System.out.println(applicationContext);

        /**
         * BeanFactory 实现类 :
         *      DefaultListableBeanFactory 非常丰富的功能
         *
         *      DefaultSingletonBeanRegistry : 单例的 Bean 对象放在这个里面管理起来了
         */

        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true);
        ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
        Map<String,Object> map  = (Map<String,Object>)singletonObjects.get(beanFactory);

//        map.forEach((k,v)->{
//            System.out.println("key:" + k + ", value = " + v);
//        });

        System.out.println("自定义的bean");
        map.entrySet().stream().filter(e-> e.getKey().startsWith("component")).forEach(
                e ->{
                    System.out.println("key:" + e.getKey() + ", value = " + e.getValue());
                }
        );

        /**
         * 3.ApplicationContext 比 BeanFactory 多的功能
         *
         */
        
        // 3.1.国际化
//        System.out.println(applicationContext.getMessage("hi",null, Locale.CHINA));
        
        // 3.2.通过通配符获取资源
        Resource[] resources = applicationContext.getResources("classpath*:META-INF/spring.factories");
        for (Resource resource : resources) {
            System.out.println(resource);
        }

        // 3.3.获取环境变量,不区分大小写 ，系统环境变量，配置的变量都可以获取
        System.out.println(applicationContext.getEnvironment().getProperty("java_home"));
        System.out.println(applicationContext.getEnvironment().getProperty("server.port"));

        // 4.事件发布
        applicationContext.publishEvent(new UserRegisterSendSmsEvent(applicationContext));


        // 4.1.事件解耦
        Component01 component01 = (Component01)applicationContext.getBean("component01");
        component01.register();



    }
}
